package com.lsc.jiujia.service;

import com.lsc.jiujia.entity.IPEntity;
import com.lsc.jiujia.mapper.IpMapper;
import com.lsc.jiujia.util.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;


@Slf4j
public class IPPool {

    @Autowired
    private IpMapper ipMapper;
    //成员变量（非线程安全）
    private List<IPEntity> ipMessages;

    public IPPool(List<IPEntity> ipMessages) {
        this.ipMessages = ipMessages;
    }

    public void getIP(List<String> urls) {
        String ipAddress;
        String ipPort;

        for (int i = 0; i < urls.size(); i++) {
            /** 随机挑选代理IP(仔细想了想，本步骤由于其他线程有可能在位置确定之后对ipMessages数量进行
             * 增加，虽说不会改变已经选择的ip代理的位置，但合情合理还是在对共享变量进行读写的时候要保证
             * 其原子性，否则极易发生脏读)
             */
            //每个线程先将自己抓取下来的ip保存下来并进行过滤与检测
            List<IPEntity> ipMessages1 = new ArrayList<>();
            String url = urls.get(i);

            synchronized (ipMessages) {
                int rand = (int) (Math.random()*ipMessages.size());
                log.info("当前线程 " + Thread.currentThread().getName() + " rand值: " + rand +
                        " ipMessages 大小: " + ipMessages.size());
                ipAddress = ipMessages.get(rand).getIPAddress();
                ipPort = ipMessages.get(rand).getIPPort();
                log.info("当前线程 ip" + ipAddress + " ipPort值: " + ipPort );
            }

            //这里要注意Java中非基本类型的参数传递方式，实际上都是同一个对象
            boolean status = IPUtil.urlParse(url, ipAddress, ipPort, ipMessages1);
            //如果ip代理池里面的ip不能用，则切换下一个IP对本页进行重新抓取
            if (!status) {
                i--;
                continue;
            } else {
                log.info("线程：" + Thread.currentThread().getName() + "已成功抓取 " +
                        url + " ipMessage1：" + ipMessages1.size());
            }
            //对ip重新进行过滤，只要速度在两秒以内的并且类型为HTTPS的
            /*ipMessages1 = IPFilter.Filter(ipMessages1);*/

            //对ip进行质量检测，将质量不合格的ip在List里进行删除
            IPUtil.IPIsable(ipMessages1);
            //将检测合适可用的IP地址保存到数据库中，等调用秒杀接口时自动分配地址
            for(IPEntity ipEntity: ipMessages1){
                ipMapper.save(ipEntity);
            }



           /* //将质量合格的ip合并到共享变量ipMessages中，进行合并的时候保证原子性
            synchronized (ipMessages) {
                log.info("线程" + Thread.currentThread().getName() + "已进入合并区 " +
                        "待合并大小 ipMessages1：" + ipMessages1.size());
                ipMessages.addAll(ipMessages1);
            }*/
        }
    }
}

